package ArithmeticObjects;
import java.util.*;

import utils.ByteTree;

/**
 * Representing an array of product ring elements
 * @author Idan
 */
public class ProductRingArray extends ElementArray {

	private List<ProductRingElement> lst;
	private Ring Zq; 
	
	/**
	 * creates a ProductRingArray from the given ByteTree representing it and a Group indicating its order
	 * @param bt ByteTree representing the ProductRingArray
	 * @param Zq Ring indicating its order
	 * @throws Exception if the construction failed
	 */
	public ProductRingArray(ByteTree bt, Ring Zq) throws Exception {
		this.Zq = Zq;
		lst = new ArrayList<ProductRingElement>();
		ByteTree left = bt.getChild(0);
		ByteTree right = bt.getChild(1);
		if (left.getNumOfChildren() != right.getNumOfChildren())
			throw new Exception("Wrong ProductRingArray format, number of right node is different from left node");
		int size = right.getNumOfChildren();
		ProductRingElement p;
		for (int i=0; i < size; i++) {
			p = new ProductRingElement(ByteTree.CreateNode().AddChildToNode(right.getChild(i))
					.AddChildToNode(left.getChild(i)), Zq);
			lst.add(p);
		}
	}
	
	@Override
	public ProductRingElement getElementForIndex(int i) {
		return lst.get(i);
	}
	
	@Override
	public void addElement(Element e) throws Exception
	{
		if (!(e instanceof ProductRingElement))
			throw new Exception("Wrong class, Expected: ProductRingElement, got: " + e.getClass().getName());
		lst.add((ProductRingElement)e);
	}
	
	/**
	 * @return the ProductRingArray's order
	 */
	public Element getOrder() {
		return Zq.getOrder();
	}
	
	@Override
	public int getArraySize() {
		return lst.size();
	}
	
	@Override
	public String toString() {
		String s = "";
		for (int i=0; i<lst.size(); i++)
			s += lst.get(i).toString()+"\n";
		return s;
	}
	
	//irrelevant for ProductRingArray
	@Override
	public ElementArray arrayMultiply(ElementArray Ea) throws Exception {
		return null;
	}

	@Override
	public ByteTree getByteTree() throws Exception {
		ByteTree rightBt = ByteTree.CreateNode();
		ByteTree leftBt = ByteTree.CreateNode();
		for (int i=0; i < this.getArraySize(); i++) {
			leftBt.AddChildToNode(lst.get(i).getByteTree().getChild(0));
			rightBt.AddChildToNode(lst.get(i).getByteTree().getChild(1));
		}
		return ByteTree.CreateNode().AddMultiChildsToNode(rightBt,leftBt);
	}
}
